﻿using System;
using Dgg.Anug.Cqrs.Core.Domain.Admin.Events;
using Dgg.Anug.Cqrs.Core.Infrastructure;
using Dgg.Anug.Cqrs.Core.Infrastructure.Eventing;

namespace Dgg.Anug.Cqrs.Core.Domain.Admin
{
	public class AppVersion
	{
		public AppVersion(string name)
		{
			OnCreating(Comb.Generate(), name);
		}
		private bool doCreate(VersionCreated e)
		{
			Id = e.ReceiverId;
			Name = e.Name;
			return true;
		}

		public AppVersion(Guid id, string name)
		{
			Id = id;
			Name = name;
		}

		public Guid Id { get; private set; }
		public Solution Solution { get; private set; }
		public string Name { get; private set; }

		public AppVersion Rename(string newName)
		{
			OnRenaming(Name, newName);
			return this;
		}
		private bool doRename(VersionRenamed e)
		{
			Name = e.NewName;
			return true;
		}

		public AppVersion Assign(Solution solution)
		{
			OnAssigning(Solution, solution);
			return this;
		}
		private bool doAssign(VersionAssigned e)
		{
			Solution = e.NewlyAssigned;
			return true;
		}

		public event DomainEventHandler<VersionRenamed> Renaming;
		protected virtual void OnRenaming(string oldName, string newName)
		{
			DomainEventHandler<VersionRenamed> handler = Renaming;
			if (handler != null) handler(this, new DomainEventEventArgs<VersionRenamed>(
				new VersionRenamed(Id) { OldName = oldName, NewName = newName },
				doRename));
		}

		/// <summary>
		/// STATIC, do unsubscribe from it
		/// </summary>
		public static event DomainEventHandler<VersionCreated> Creating;
		// not virtual as is called from the ctor
		protected void OnCreating(Guid id, string name)
		{
			DomainEventHandler<VersionCreated> handler = Creating;
			if (handler != null) handler(this, new DomainEventEventArgs<VersionCreated>(
				new VersionCreated(id) { Name = name },
				doCreate));
		}

		public event DomainEventHandler<VersionAssigned> Assigning;
		protected virtual void OnAssigning(Solution previouslyAssigned, Solution newlyAssigned)
		{
			DomainEventHandler<VersionAssigned> handler = Assigning;
			if (handler != null) handler(this, new DomainEventEventArgs<VersionAssigned>(
				new VersionAssigned(Id) { PreviouslyAssigned = previouslyAssigned, NewlyAssigned = newlyAssigned },
				doAssign));
		}
	}
}
